﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Collections;

namespace CitrixPVSWrapper
{
    
    [System.Management.Automation.Cmdlet("Run", "PvsCopyPasteServer", SupportsShouldProcess = true)]
    public class Run_PvsCopyPasteServer : System.Management.Automation.PSCmdlet
    {
        [Parameter(Mandatory = false)]
        public PvsServer SourceServer;

        [Parameter(Mandatory = false)]
        public String SourceServerId;

        [Parameter(Mandatory = false)]
        public String SourceServerName;

        [Parameter(Mandatory = false)]
        public PvsServer DestinationServer;

        [Parameter(Mandatory = false)]
        public String DestinationServerId;

        [Parameter(Mandatory = false)]
        public String DestinationServerName;

        [Parameter(Mandatory = false)]
        public ServerPropertySet[] Properties;

        protected override void BeginProcessing()
        {
            // Test for mutually exclusive parameters
            Validate.MutuallyExclusiveParameters(this.MyInvocation.BoundParameters, new string[] { "SourceServer", "SourceServerId", "SourceServerName" },true);
            Validate.MutuallyExclusiveParameters(this.MyInvocation.BoundParameters, new string[] { "DestinationServer", "DestinationServerId", "DestinationServerName" }, true);

            // Test that the supplied Source Server exists
            if (MyInvocation.BoundParameters.ContainsKey("SourceServer")) 
            {
                if (Get_PvsServer_Internal.Get_ServerById(this.SourceServer.ServerId).Count == 1)
                {
                    this.SourceServerId = this.SourceServer.ServerId;
                    this.SourceServerName = this.SourceServer.ServerName;
                }
                else
                {
                    throw new ParameterBindingException("The specified Source Server could not be found");
                }
            }
            else if (MyInvocation.BoundParameters.ContainsKey("SourceServerId")) 
            {
                if (Get_PvsServer_Internal.Get_ServerById(this.SourceServerId).Count == 1)
                {
                    this.SourceServer = Get_PvsServer_Internal.Get_ServerById(this.SourceServerId).First();
                    this.SourceServerName = this.SourceServer.ServerName;
                }
                else
                {
                    throw new ParameterBindingException("The specified Source Server Id could not be found");
                }
            }
            else if (MyInvocation.BoundParameters.ContainsKey("SourceServerName")) 
            {
                if (Get_PvsServer_Internal.Get_ServerByName(this.SourceServerName).Count == 1)
                {
                    this.SourceServer = Get_PvsServer_Internal.Get_ServerByName(this.SourceServerName).First();
                    this.SourceServerId = this.SourceServer.ServerId;
                }
                else
                {
                    throw new ParameterBindingException("The specified Source Server name could not be found");
                }
            }

            // Test that the supplied Destination Server exists
            if (MyInvocation.BoundParameters.ContainsKey("DestinationServer"))
            {
                if (Get_PvsServer_Internal.Get_ServerById(this.DestinationServer.ServerId).Count == 1)
                {
                    this.DestinationServerId = this.DestinationServer.ServerId;
                    this.DestinationServerName = this.DestinationServer.ServerName;
                }
                else
                {
                    throw new ParameterBindingException("The specified Destination Server could not be found");
                }
            }
            else if (MyInvocation.BoundParameters.ContainsKey("DestinationServerId"))
            {
                if (Get_PvsServer_Internal.Get_ServerById(this.DestinationServerId).Count == 1)
                {
                    this.DestinationServer = Get_PvsServer_Internal.Get_ServerById(this.DestinationServerId).First();
                    this.DestinationServerName = this.DestinationServer.ServerName;
                }
                else
                {
                    throw new ParameterBindingException("The specified Destination Server Id could not be found");
                }
            }
            else if (MyInvocation.BoundParameters.ContainsKey("DestinationServerName"))
            {
                if (Get_PvsServer_Internal.Get_ServerByName(this.DestinationServerName).Count == 1)
                {
                    this.DestinationServer = Get_PvsServer_Internal.Get_ServerByName(this.DestinationServerName).First();
                    this.DestinationServerId = this.DestinationServer.ServerId;
                }
                else
                {
                    throw new ParameterBindingException("The specified Destination Server name could not be found");
                }
            }
        }

        protected override void ProcessRecord()
        {
            // Verbose and Debug Settings
            Boolean Verbose = this.MyInvocation.BoundParameters.ContainsKey("Verbose");
            WriteVerbose("Verbose Flag: " + Verbose);
            Boolean Debug = this.MyInvocation.BoundParameters.ContainsKey("Debug");
            WriteDebug("Debug Flag: " + Debug);

            // Collections to hold the queries and the results
            string TargetObject = "CopyPasteServer";

            //Build the query object
            QueryDefinition RunQuery = new QueryDefinition(QueryActionType.Run, TargetObject);

            RunQuery.Parameters.Add("serverIdFrom=\"" + this.SourceServerId + "\"");
            RunQuery.Parameters.Add("serverId=\"" + this.DestinationServerId + "\"");
            if (this.MyInvocation.BoundParameters.ContainsKey("Properties")) { RunQuery.Parameters.Add("properties=" + String.Join(",", this.Properties.ToString())) ;}

            string ShouldProcessMessage = String.Format("Copy properties from server {0} to server {1}", this.SourceServerName, this.DestinationServerName);

            // Perform the actual Run and return any errors
            if (ShouldProcess(ShouldProcessMessage))
            {
                MCliReturnObject Return = PvsHelpers.ExecuteMcliAction(RunQuery, Verbose, Debug);
                if (Return.ReturnState == ReturnState.Error) { foreach (ErrorRecord Error in Return.Errors) { WriteError(Error); } }
            }

        }
    }

    // Property set to be used for specifying the properties to be copied between devices. 
    public enum ServerPropertySet
    {
        Configuration = 1,
        Port = 2, 
        ActiveDirectory = 4,
        AdvancedServer = 5,
        AdvancedNetwork = 6,
        AdvancedPacing =7,
        AdvancedDevice = 8,
        Logging = 9
    }

}
